﻿package net.wangit.dev.wizard;

import java.util.List;
import java.util.Map;

import net.wangit.LabelUtil;
import net.wangit.context.ActionContext;
import net.wangit.dev.ObjectIdValidator;
import net.wangit.framework.validation.ValidationResult;
import net.wangit.framework.validation.ValidationUtil;
import net.wangit.jdbc.DB;
import net.wangit.jdbc.DBImplementor;
import net.wangit.jdbc.database.Database;
import net.wangit.jdbc.table.Column;
import net.wangit.jdbc.table.TableMeta;
import net.wangit.jdbc.table.TableMetaFactory;
import net.wangit.util.Checker;
import net.wangit.view.element.ElementComponent;
import net.wangit.view.element.util.ElementUtil;


public class WizardUtil {

	public WizardUtil() {
	}

	public static final String getListUnitSql(String tableName) {
		return (new StringBuilder("select * from ")).append(tableName)
				.toString();
	}

	public static final String getFormUnitSql(DB db, String domain,
			String tableName, String unitId) {
		StringBuffer sql = new StringBuffer("select * from ");
		sql.append(tableName).append(" where 1=1 $SQL[[");
		Database database = ((DBImplementor) db).getJDBCSettings()
				.getDatabase();
		TableMeta meta = TableMetaFactory.getTableMeta(domain, tableName);
		List<Column> columns = meta.getPrimaryKey().getColumns();
		for (int i = 0; i < columns.size(); i++) {
			Column column = columns.get(i);
			String name = column.getName();
			String alias = ElementUtil.getAlias(unitId, name);
			String value = (new StringBuilder("$RS{")).append(alias)
					.append(",").append(domain).append(".").append(alias)
					.append("}").toString();
			String option = database.getQueryOption(column.getType(), null,
					name, value, true);
			sql.append(" and ").append(option);
		}

		sql.append("]]");
		return sql.toString();
	}

	public static final String getSonListUnitSql(DB db, String domain,
			String sonTableName, String fatherTableName,
			Map<String, String> father2SonFields, String fatherFormUnitId) {
		StringBuffer sql = new StringBuffer("select * from ");
		sql.append(sonTableName).append(" where 1=1 $SQL[[");
		Database database = ((DBImplementor) db).getJDBCSettings()
				.getDatabase();
		TableMeta fatherMeta = TableMetaFactory.getTableMeta(domain,
				fatherTableName);
		TableMeta sonMeta = TableMetaFactory.getTableMeta(domain, sonTableName);
		List<Column> columns = fatherMeta.getPrimaryKey().getColumns();
		for (int i = 0; i < columns.size(); i++) {
			Column fatherColumn = columns.get(i);
			String fatherColumnName = fatherColumn.getName();
			String alias = ElementUtil.getAlias(fatherFormUnitId,
					fatherColumnName);
			String value = (new StringBuilder("$RS{")).append(alias)
					.append(",").append(domain).append(".").append(alias)
					.append("}").toString();
			String sonColumnName = father2SonFields.get(fatherColumnName);
			Column sonColumn = sonMeta.getColumn(sonColumnName);
			String option = database.getQueryOption(sonColumn.getType(), null,
					sonColumnName, value, true);
			sql.append(" and ").append(option);
		}

		sql.append("]]");
		return sql.toString();
	}

	public static final String getElementId(String id, List<String> elements) {
		if (!elements.contains(id))
			return id;
		int suffix = 2;
		while (elements.contains((new StringBuilder(String.valueOf(id)))
				.append(suffix).toString())) {
			suffix++;
		}
		return (new StringBuilder(String.valueOf(id))).append(suffix)
				.toString();
	}

	public static String getNewUrl(String domain, String pageId) {
		StringBuffer url = new StringBuffer("/");
		url.append(domain).append("/").append(pageId).append(".do?")
				.append("m").append("=").append("a");
		return url.toString();
	}

	public static String getActionUrl(String domain, String unitId,
			String elementId) {
		StringBuffer url = new StringBuffer("/");
		url.append(domain).append("/").append(unitId).append("/").append(
				elementId).append(".do");
		return url.toString();
	}

	public static String getListUrl(String domain, String pageId,
			String unitId, String unitShowMode, String tableName) {
		StringBuffer url = new StringBuffer("/");
		url.append(domain).append("/").append(pageId).append(".do?")
				.append("m").append("=").append(unitShowMode).append(
						getPrimaryKeyParameters(domain, tableName, unitId));
		return url.toString();
	}

	private static StringBuffer getPrimaryKeyParameters(String domain,
			String tableName, String unitId) {
		StringBuffer parameters = new StringBuffer();
		TableMeta meta = TableMetaFactory.getTableMeta(domain, tableName);
		List<Column> columns = meta.getPrimaryKey().getColumns();
		for (int i = 0; i < columns.size(); i++) {
			String name = columns.get(i).getName();
			parameters.append("&").append(ElementUtil.getAlias(unitId, name))
					.append("=").append("$D{").append(name).append("}");
		}

		return parameters;
	}

	public static void validateUnitId(DB db, ActionContext ac,
			ValidationResult vr, ElementComponent ec, String unitIdValue)
			throws Exception {
		if (ValidationUtil.isNotNull(vr, ac, unitIdValue, ec))
			if (!ObjectIdValidator.valid(unitIdValue)) {
				String error = LabelUtil.get(ac, "dev",
						"validation.invalid_object_id");
				vr.addError(0, ec.getId(), ValidationUtil.getMessage(ac, ec,
						unitIdValue, error, false, 0));
			} else if (ComponentUtil.existentUnit(db, unitIdValue)) {
				String error = LabelUtil.get(ac, "dev",
						"wizard.unitid_existent");
				vr.addError(0, ec.getId(), ValidationUtil.getMessage(ac, ec,
						unitIdValue, error, false, 0));
			}
	}

	public static void validateTable(DB db, ActionContext ac,
			ValidationResult vr, ElementComponent ec, String tableName)
			throws Exception {
		if (!ComponentUtil.hasPrimaryKey(db, tableName)) {
			String error = LabelUtil.get(ac, "dev", "wizard.invalid_table");
			vr.addError(0, ec.getId(), ValidationUtil.getMessage(ac, ec,
					tableName, error, false, 0));
		}
	}

	public static String getUrl(String domain, String pageId, String showMode) {
		StringBuffer url = new StringBuffer("/");
		url.append(domain).append("/").append(pageId).append(".do");
		if (!Checker.isEmpty(showMode))
			url.append("?").append("m").append("=").append(showMode);
		return url.toString();
	}

	public static String getFatherSonDeleteCommand(String fatherTableName,
			String fatherUnitId, String sonTableName, String linkedFields) {
		StringBuffer command = new StringBuffer(fatherTableName);
		command.append("(").append(sonTableName).append(":").append(
				linkedFields).append(")").append(",").append(fatherUnitId);
		return command.toString();
	}
}
